
/**
 * this class encapsulates calculations and data
 * for every regular polygon (with n-edges).
 * if there are polygons with 3- or 4- edges
 * it's better to use equilateral triangle or square
 */
public class RegularPolygon implements ScaleablePolygon {

	private double sideLength;
	private final int EDGES;
	
	/**
	 * a regular polygon consists of n edges and
	 * a positive length-value.
	 */
	public RegularPolygon(double sideLength, int edges) {
		validateEdges(edges);
		set(sideLength);
		this.EDGES = edges;
	}
	
	/**
	 * the scalar must be positiv and not zero ( > 0)
	 * the scalar changes the size of all length-values
	 */
	@Override
	public void scale(double factor) {
		if(factor <= 0) { //scalar > 0
			throw new IllegalArgumentException();
		}
		set(sideLength * factor);
	}

	/**
	 * returns the number of edges
	 * this value is > 2
	 */
	@Override
	public int edges() {
		return EDGES;
	}

	/**
	 * calculates the area of the polygon
	 * using the number of edges and the length of each side
	 */
	@Override
	public double area() {
		double apothem = getS() / (2 * Math.tan(Math.PI / edges()));
		double area = 0.5 * apothem * perimeter();
		return area;
	}

	/**
	 * calculates the perimeter of the polygon
	 * using the number of edges and the length of each side
	 */
	@Override
	public double perimeter() {
		return edges() * getS();
	}

	/**
	 * sets the length for an regular polygon
	 * length must be positive
	 */
	public void set(double s) {
		validateSideLength(s);
		this.sideLength = s;
	}
	
	public double getS() {
		return sideLength;
	}
	
	/**
	 * lenght must be > 0
	 */
	private void validateSideLength(double sideLength) {
		if(sideLength <= 0) {
			throw new IllegalArgumentException();
		}
	}
	
	/**
	 * number of edges must be > 2
	 */
	private void validateEdges(int edges) {
		if(edges < 3) {
			throw new IllegalArgumentException();
		}
	}
}
